
package com.simple.mqtt.server.domain;

import com.simple.mqtt.server.config.MqttBrokerConfig;
import com.simple.mqtt.server.processor.MqttBrokerProcessor;
import io.netty.channel.ChannelHandlerContext;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.net.InetSocketAddress;
import java.util.function.Supplier;

/**
 * 客户端信息
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class ClientInfo implements Serializable {

    private String clientId;
    private String username;
    private long keepAlive;
    private boolean connected;
    private String protoName;
    private int protoVer;
    private String protoFullName;
    private String ipAddress;
    private int port;
    private Long connectedAt;
    private long createdAt;
    private int decodeQueueSize;
    private int handlerQueueSize;
    private int sendQueueSize;

    public static ClientInfo from(ChannelHandlerContext context, MqttBrokerConfig config) {
        return from(context, config, ClientInfo::new);
    }

    public static ClientInfo from(ChannelHandlerContext context, MqttBrokerConfig config, Supplier<ClientInfo> extFunc) {
        ClientInfo clientInfo = extFunc.get();

        String clientId = context.channel().attr(MqttBrokerProcessor.CLIENT_ID_ATTR).get();
        String username = context.channel().attr(MqttBrokerProcessor.USERNAME_ATTR).get();

        clientInfo.setClientId(clientId);
        clientInfo.setUsername(username);
        clientInfo.setConnected(context.channel().isActive());
        clientInfo.setKeepAlive(60L);

        InetSocketAddress remoteAddress = (InetSocketAddress) context.channel().remoteAddress();
        if (remoteAddress != null) {
            clientInfo.setIpAddress(remoteAddress.getAddress().getHostAddress());
            clientInfo.setPort(remoteAddress.getPort());
        }

        clientInfo.setProtoName("MQTT");
        clientInfo.setProtoVer(4);
        clientInfo.setProtoFullName("MQTT 3.1.1");

        long now = System.currentTimeMillis();
        clientInfo.setConnectedAt(now);
        clientInfo.setCreatedAt(now);

        clientInfo.setDecodeQueueSize(0);
        clientInfo.setHandlerQueueSize(0);
        clientInfo.setSendQueueSize(0);

        return clientInfo;
    }
}
